<?php

namespace app\api\controller;

use app\api\model\PushMember;
use think\Request;
use think\Db;
use think\Log;

use AlibabaCloud\SDK\Push\V20160801\Push as PushModel;
use Darabonba\OpenApi\Models\Config;
use AlibabaCloud\SDK\Push\V20160801\Models\MassPushRequest\pushTask;
use AlibabaCloud\SDK\Push\V20160801\Models\MassPushRequest;
use AlibabaCloud\Tea\Exception\TeaUnableRetryError;
use GatewayClient\Gateway;

class Push extends Common
{
    protected $appkey;
    protected $option;

    protected $client;
    
    public function __construct(Request $request = null)
    {
        parent::__construct($request);
        
        $config = new Config([
            "accessKeyId" => getenv('ALIBABA_PUSH_KEY'),
            "accessKeySecret" => getenv('ALIBABA_PUSH_SECRET')
        ]);

        $config->endpoint = "cloudpush.aliyuncs.com";
    
        $client = new PushModel($config);
    
        $this->client = $client;
    
        $this->appkey = getenv('ALIBABA_PUSH_APPKEY');
        $this->option = [
            // Boolean, 可选, 离线消息/通知是否保存。StoreOffline默认设置为false。  若保存，在推送时候用户不在线，在过期时间（ExpireTime）内用户上线时会被再次发送。ExpireTime默认为72小时。iOS通知走APNs链路，不受StoreOffline影响。
            'storeOffline' => true,
            
  
            // String, 可选, iOS的通知是通过APNs中心来发送的，需要填写对应的环境信息。  - DEV：表示开发环境。 - PRODUCT：表示生产环境。
            'iOSApnsEnv' => 'PRODUCT',
            // Boolean, 可选, 是否开启角标自增功能，默认为false。  >当该项为true时，iOSBadge必须为空。  角标自增功能由推送服务端维护每个设备的角标计数，需要用户使用V1.9.5以上版本的sdk，并且需要用户主动同步角标数字到服务端。
            'iOSBadgeAutoIncrement' => true,
            // String, 可选, 通知的提醒方式。可取值：  - **VIBRATE**：振动（默认值） - **SOUND**：声音 - **BOTH**：声音和振动 - **NONE**：静音
            'androidNotifyType' => 'BOTH',
            // String, 必填, 推送目标。可取值：  - DEVICE：根据设备推送。 - ACCOUNT：根据账号推送。 - ALIAS：根据别名推送。
            'target' => 'ALIAS',
            // String, 必填, 设备类型，取值范围为：  - iOS：iOS设备 - ANDROID：Android设备 - ALL：全部类型设备  > 该参数仅对旧的不分端App有意义。新的分端App下，该参数填写”ALL”或与App分端类型对应的值均可。
            'deviceType' => 'ANDROID',
            // String, 必填, 推送类型。取值：  - MESSAGE：表示消息。 - NOTICE：表示通知。
            'pushType' => 'NOTICE',
            // String, 可选, 设置NotificationChannel参数，具体用途请参见[常见问题：Android 8.0以上设备通知接收不到](https://help.aliyun.com/knowledge_detail/67398.html)。
            //荣耀（分类审核中）
            //  'androidNotificationHonorChannel'=>'LOW',
            //华为
              'androidMessageHuaweiCategory'=>'IM',
              //vivo
              'androidNotificationVivoChannel'=>1,
            //   'androidMessageVivoCategory '=>'IM',
            //  'androidMessageOppoCategory'=>'IM',
            //  'androidMessageOppoNotifyLevel'=>2,
            //小米
             'androidNotificationXiaomiChannel' => '135820',
            //oppo
              'androidNotificationChannel' => '135820',
            // String, 可选, 指定点击通知后跳转的Activity。
            // "androidPopupActivity" => "com.apicloud.aliyunPush.PopupPushActivity",
            "androidPopupActivity" => "com.xiaomi.huawei.push.XiaoMiPushActivity",
               //  "androidPopupActivity" => "com.alibaba.push.PopupActivity",
            
        ];
    }
    
    protected function massPush($alias, $title, $body, $data, $ios = 0)
    {
        try {
            $tasks = [];
            foreach ($alias as $item) {
                $option = $this->option;
                
                $option['title'] = $option['androidPopupTitle'] = $title;
                $option['body'] = $option['androidPopupBody'] = $body;
                $option['targetValue'] = implode(',', $item);
                if ($data) {
                    if ($ios) {
                        $option['iOSExtParameters'] = $data;
                    } else {
                        $option['androidExtParameters'] = $data;
                    }
                }
            
                
                $tasks[] = new pushTask($option);
            }
            if (sizeof($tasks) == 0) {
                return ['code' => 400, 'msg' => 'empty task'];
            }
            $massPushRequest = new MassPushRequest([
                "pushTask" => $tasks,
                "appKey" => $this->appkey
            ]);
        
            $this->client->massPush($massPushRequest);
        } catch (TeaUnableRetryError $e) {
            Log::write('error:massPush:'.implode(',', $alias).':'.$title.':'.$body.':'.$data.':'.$ios .':'. $e->getMessage());
            return ['code' => 400, 'msg' => $e->getMessage()];
            return ['code' => 400, 'msg' => $e->getErrorInfo()['code']];
        }
    
        return ['code' => 200, 'msg' => '推送成功'];
    }
    
    public function send($alias, $channel, $title, $body, $data='')
    {
        if (is_null($alias)) return true;
        $oldalias = $alias;
        try {
            $where = ['cid' => $channel];
            $ios = 0;
            if ($alias !== 'ALL') {
                $alias = array_filter(explode(',', $alias));

                $aliasFilter = [];
                foreach ($alias as $key => $value) {
                    $unpush = Db::name('user')->where(['id'=>$value])->value('unpush');
                    if(!$unpush){
                        $aliasFilter[] = $value;
                    }
                }
                $alias = $aliasFilter;

                $where['user_id'] = ['in', $alias];

                if (sizeof($alias) == 1) {
                    $user_repeat_check = Db::name('user_repeat_check')->where(['user_id'=>$alias[0]])->find();
                    if ($user_repeat_check) {
                        // if ($user_repeat_check['sys_channel'] != getenv('APP_CHANNEL')) {
                        //     return http_get('http://'.getenv('APP_URL_'.$user_repeat_check['sys_channel']).'/api/push/send?'.'alias='.$oldalias . '&channel='.$channel . '&title='.$title . '&body='.$body . '&data='.$data);
                        // }
                        if ($user_repeat_check['os']) {
                            $result = getUserAgent($user_repeat_check['os']);
                            if ($result == 'ios') {
                                $this->appkey = getenv('ALIBABA_PUSH_IOS_APPKEY');
                                $ios = 1;
                            }
                        }
                        $version_lower = Db::name('config_system')->where(['title'=>'newpush_app_version_lower'])->value('content');
                        if ($user_repeat_check['last_login_app_version'] >= $version_lower) {
                            $this->option['androidNotificationChannel'] = '135820';
                        }
                    }
                }
            }
            // var_dump($this->option);exit;


            $users = PushMember::get($where);
            
            if (!$users) return json(['code' => 400, 'msg' => '无目标']);
            
            $title = mb_substr(trim(strip_tags($title)), 0, 20, 'utf8');
            $body = mb_substr(trim(strip_tags($body)), 0, 50, 'utf8');
            
            $alias = array_chunk($alias, 1000);
        
            $response = $this->massPush($alias, $title, $body, $data, $ios);
            return json($response);
        } catch (\Exception $e) {
            Log::write('error:pushsend:' . $oldalias . ':' . $channel . ':'. $title . ':' . $body . ':' . $data . ':' . $e->getMessage());
        }
    }
    
}
